/*************************************************************/
/*                           MD2.H                           */
/*                                                           */
/* Purpose: Definitions for CMd2, a class to load, render and*/
/*          animate id Software's .md2 file format.  Also    */
/*          contains all nessasary data structures for MD2   */
/*                                                           */
/*************************************************************/

#ifndef __MODELEDITOR_MD2_H
#define __MODELEDITOR_MD2_H

#include "../ModelEditorConfig.h"
#include "Model.h"

//- SMD2Header - Header for all Md2 files
struct SMD2Header
{
	int m_iMagicNum;		// Always IDP2 (844121161)
	int m_iVersion;			// 8
	int m_iSkinWidthPx;		// texture width in pixels
	int m_iSkinHeightPx;	// texture height in pixels
	int m_iFrameSize;		// each keyframe size in bytes
	int m_iNumSkins;		// total number of skin options for model
	int m_iNumVertices;		
	int m_iNumTexCoords; 
	int m_iNumTriangles; 
	int m_iNumGLCommands; 
	int m_iNumFrames;		// number of frames
	int m_iOffsetSkins; 
	int m_iOffsetTexCoords; 
	int m_iOffsetTriangles; 
	int m_iOffsetFrames; 
	int m_iOffsetGlCommands; 
	int m_iFileSize; 
};

//-------------------------------------------------------------
//- SMD2Vert - Vertex structure for MD2
struct SMD2Vert
{
	float m_fVert[3];
	unsigned char m_ucReserved;
};

//-------------------------------------------------------------
//- SMD2Frame - Frame information for the model file 
struct SMD2Frame
{
	float m_fScale[3];
	float m_fTrans[3];
	char m_caName[16];
	SMD2Vert *m_pVerts;

	//Cleans up after itself
	SMD2Frame()
	{
		m_pVerts = NULL;
	}

	~SMD2Frame()
	{
		if(m_pVerts)
			delete [] m_pVerts;
		m_pVerts = NULL;
	}
};

//-------------------------------------------------------------
//- SMD2Triangle - Triangle information for the MD2
struct SMD2Triangle
{
	unsigned short m_sVertIndices[3];
	unsigned short m_sTexIndices[3];
};

//-------------------------------------------------------------
//- SMD2TexCoord - Texture coord information for the MD2
struct SMD2TexCoord
{
	float	m_fTex[2];
};

//-------------------------------------------------------------
//- SMD2Skin - Name of a single skin in the md2 file
struct SMD2Skin
{
	char	m_caTextureName[64];	//filename
};

//-------------------------------------------------------------
class CMd2 : public CModel
{
public:
	// Set skin to one of the files specified in the md2 files itself
	void SetTexture(unsigned int SkinID, int uiTex);

	// Set outer custom texture
	void SetCustomTexture(bool bCustomTex)	{ m_bIsCustomTex = bCustomTex;	}
	UINT GetTextureNum()					{ return m_Head.m_iNumSkins;	}

	// Load the file
	virtual bool Load(const char *szFilename);
	// Sets the scaling of the model. 0.0f for no scaling.
	virtual void SetScaling( float fScale = 0.0f );
	// Get the number of Animnation from file
	virtual UINT GetAnimationListNum() { return 0; }
	virtual const char* GetAnimationName(UINT AnimID) { return NULL; }

	// Create staticmesh at the initial position
	virtual void CreateStaticMesh(UINT skinID);

	virtual void Render(float ElapsedSeconds);

	// Model Type
	virtual EModelType GetModelType() { return EModel_MD2; }

	// Get the number of Anim Frames
	void GetFrameNum(const char * szAnimName, UINT& StartFrameID, UINT& EndFrameID)
	{ StartFrameID = 0; EndFrameID = m_Head.m_iNumFrames-1; }

	//constructors/destructo
	CMd2();
	CMd2(const char *szFile);
	~CMd2();

private:	
	//Animate the md2 model based on Frame ID
	void RenderAnimate(UINT skinID, float ElapsedSeconds, float fSpeed = 30.0f, unsigned int uiStartFrame = 0, unsigned int uiEndFrame = 0, bool bLoop = true);
	
	// Texture file name in struct SMD2Skin usually has error file's extension,
	// this function find correct file's extension in local path
	bool BindCorrectTextureName(TCHAR (&TexName) [128]);
	
	SMD2Header m_Head;				// file header information
	
	SMD2Frame *m_pFrames;			// Frame information
	
	SMD2Triangle *m_pTriangles;		// Triangles information
	
	SMD2TexCoord *m_pTexCoords;		// Texure coords information
	
	SMD2Skin *m_pSkins;				// Skin information
	
	SMD2Vert *m_pCurrentVerts;		// Interpolated vertices
	
	TCHAR m_CurrentPath[128];		// current file path
	TCHAR m_CurrentTexName[128];	// current Texture name
	bool m_bIsCustomTex;			// Using a custom Texture?
	
	OY_UCOLOR_VERTEX_TYPE *m_SMVB;	// Vertex for rendering
};

#endif